using System;
using System.Collections;
using System.Diagnostics;
using System.Transactions;
using System.Workflow.Runtime;

namespace DP.Sharepoint.Workflow.InfoPath
{
    public enum FormSetValueType
    {
        InnerText = 1,
        InnerXml
    }

    [Serializable]
    public class FormSetFieldValueRequest
    {
        public IPAccessHelper IPAccessHelper;
        public string PropertyPath;
        public string PropertyValue;
        public FormSetValueType SetValueType;
    }

    [Serializable]
    internal class IPAccessService : IPendingWork
    {
        internal static readonly IPAccessService Instance = new IPAccessService();

        #region IPendingWork Members

        public void Commit(Transaction transaction, ICollection items)
        {
            int saveErrCnt = 0;

            if (items.Count > 0)
            {
                IEnumerator myItems = items.GetEnumerator();

                myItems.MoveNext();

                IPAccessHelper ip = ((FormSetFieldValueRequest) myItems.Current).IPAccessHelper;

                reprocess:

                ip.LoadForm();

                ProcessFormSetFieldValueRequests(items, ip);

                try
                {
                    ip.SaveForm();
                }
                catch
                {
                    saveErrCnt++;

                    if (saveErrCnt > 3)
                        throw;
                    
                    goto reprocess;
                }
            }
        }


        public void Complete(bool succeeded, ICollection items)
        {
        }

        public bool MustCommit(ICollection items)
        {
            return true;
        }

        #endregion

        private void ProcessFormSetFieldValueRequests(ICollection req, IPAccessHelper ip)
        {
            foreach (FormSetFieldValueRequest r in req)
            {
                try
                {
                    if (r.SetValueType == FormSetValueType.InnerText)

                        ip.SetFormValueInnerText(r.PropertyPath, r.PropertyValue);

                    else
                        ip.SetFormValueInnerXml(r.PropertyPath, r.PropertyValue);
                }
                catch (Exception e)
                {
                    Exception we = Common.WrapWithFriedlyException(e,
                                                                   string.Format(
                                                                       "Error updating in form at {0} where property path = {1} ",
                                                                       ip.FormFile.Url, r.PropertyPath));

                    EventLog.WriteEntry("DP.Sharepoint.Workflow.InfoPath.IPAccessService", we.ToString(),
                                        EventLogEntryType.Error);

                    throw we;
                }
            }
        }
    }
}